package com.fw.application.controller.open;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fw.annotation.PrintParam;
import com.fw.application.controller.FwGuessController;
import com.fw.application.controller.base.BaseController;
import com.fw.config.AliConfig;
import com.fw.core.redis.RedisCache;
import com.fw.enums.OrderState;
import com.fw.system.web.model.entity.FwOrder;
import com.fw.system.web.model.entity.FwParentOrder;
import com.fw.system.web.model.form.ShopIngAgencyForm;
import com.fw.system.web.model.form.ShopIngShangJiaForm;
import com.fw.system.web.service.*;
import com.fw.utils.JsonUtils;
import com.ijpay.alipay.AliPayApi;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 支付宝支付 回调接口
 */
@CrossOrigin
@RestController
@RequestMapping("/web/aliPay")
@Slf4j
@RequiredArgsConstructor(onConstructor_= {@Autowired})
public class AliNotifyController implements BaseController {

    private final AliConfig aliConfig;
    private final IFwParentOrderService parentOrderService;
    private final IFwOrderService orderService;
    private final IFwUserService userService;
    private final IFwShangjiaDealService shangjiaDealService;
    private final IFwShopService shopService;
    private final RedisCache redisCache;

    private final FwGuessController guessController;

    @RequestMapping(value = "/test_url")
    @ResponseBody
    public String certNotifyUrl(HttpServletRequest request) {
        try {
            // 获取支付宝POST过来反馈信息
            Map<String, String> params = AliPayApi.toMap(request);
            // 获取支付宝POST过来反馈信息
            boolean verifyResult = rsaCertCheckV1(params);
            if (verifyResult) {
                // TODO 请在这里加上商户的业务逻辑程序代码 异步通知可能出现订单重复通知 需要做去重处理
                log.info("test_url 验证成功succcess");
                return "success";
            } else {
                log.info("test_url 验证失败");
                // TODO
                return "failure";
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return "failure";
        }
    }

    @RequestMapping(value = "/spuOrderPay")
    @ResponseBody
    public String spuOrderPay(HttpServletRequest request) {
        try {
            // 获取支付宝POST过来反馈信息
            Map<String, String> params = AliPayApi.toMap(request);
            // 获取支付宝POST过来反馈信息
            boolean verifyResult = rsaCertCheckV1(params);
            if (verifyResult) {
                // 获取用户 编号
                Object out_trade_no = redisCache.getCacheObject(params.get("out_trade_no"));
                if (Objects.isNull(out_trade_no)) {
                    // TODO 请在这里加上商户的业务逻辑程序代码 异步通知可能出现订单重复通知 需要做去重处理
                    log.info("商品订单支付 spuOrderPay 验证成功succcess");
                    String parentOrderId = params.get("out_trade_no");
                    BigDecimal total_amount = new BigDecimal(params.get("total_amount"));
                    String flag = params.get("trade_status");
                    if (!"TRADE_SUCCESS".equals(flag)){
                        return "success";
                    }
                    List<FwOrder> orderList = orderService.list(Wrappers.<FwOrder>lambdaQuery()
                            .eq(FwOrder::getParentOrderId, parentOrderId));
                    FwParentOrder parentOrder = parentOrderService.getById(parentOrderId);
                    if (!OrderState.PENDING_PAYMENT.getCode().equals(parentOrder.getState())) {
                        return "success";
                    }
                    log.info("parentOrder = " + parentOrder.toString());
                    //状态修改
                    parentOrderService.update(Wrappers.<FwParentOrder>lambdaUpdate()
                            .set(FwParentOrder::getState, OrderState.TO_BE_DELIVERED.getCode())
                            .eq(FwParentOrder::getParentOrderId, parentOrderId));
                    orderList.forEach(order -> {
                        orderService.update(Wrappers.<FwOrder>lambdaUpdate()
                                .set(FwOrder::getStatus, OrderState.TO_BE_DELIVERED.getCode())
                                .set(FwOrder::getUpdateTime, LocalDateTime.now())
                                .set(FwOrder::getPayType, OrderState.PAY_TYPE_ALI.getCode())//支付宝支付
                                .set(FwOrder::getOutTradeNo, parentOrderId) //订单系统编号就是ParendOrderId，单次支付唯一
                                .eq(FwOrder::getId, order.getId()));
                        //todo 判断是否竞猜订单
                        if (order.getIsQuiz() == 1) {
                            log.info("***********************************竞猜订单**********************************" + order.getId());
                            guessController.payAfter(order.getId(), parentOrder.getUserId());
                        }
                    });
                    redisCache.setCacheObject(out_trade_no.toString(),out_trade_no);
                }
                return "success";
            } else {
                log.info("test_url 验证失败");
                // TODO

                return "failure";
            }

        } catch (AlipayApiException e) {
            log.info(e.getErrMsg());
            e.printStackTrace();
            return "failure";
        }
    }

    @RequestMapping(value = "/agency_url")
    @ResponseBody
    public String agencyCertNotifyUrl(HttpServletRequest request) {
        try {
            // 获取支付宝POST过来反馈信息
            Map<String, String> params = AliPayApi.toMap(request);
            // 获取支付宝POST过来反馈信息
            boolean verifyResult = rsaCertCheckV1(params);
            if (verifyResult) {
                // TODO 请在这里加上商户的业务逻辑程序代码 异步通知可能出现订单重复通知 需要做去重处理

                //获取回调信息
                String out_trade_no = params.get("out_trade_no");
                BigDecimal total_amount = new BigDecimal(params.get("total_amount"));
                String flag = params.get("trade_status");
                if (!"TRADE_SUCCESS".equals(flag)){
                    return "success";
                }
                String passback_params = params.get("passback_params");
                ShopIngAgencyForm shopIngAgencyForm = JsonUtils.jsonToPojo(passback_params, ShopIngAgencyForm.class);

                //充实Form
                shopIngAgencyForm.setLogShopIngAgencyId(out_trade_no);//填充日志编号
                shopIngAgencyForm.setMoney(total_amount);
                userService.ShopIngAgent(shopIngAgencyForm);


                log.info("agency_url 验证成功succcess");
                return "success";
            } else {
                log.info("agency_url 验证失败");
                // TODO
                return "failure";
            }
        } catch (Exception e) {
            e.printStackTrace();
            return "failure";
        }
    }

    @RequestMapping(value = "/shopIng_shangJia_pay_url")
    @ResponseBody
    @PrintParam
    public String shopIngShangJiaNotifyUrl(HttpServletRequest request) {
        try {
            // 获取支付宝POST过来反馈信息
            Map<String, String> params = AliPayApi.toMap(request);
            // 获取支付宝POST过来反馈信息
            boolean verifyResult = rsaCertCheckV1(params);
            if (verifyResult) {
                // TODO 请在这里加上商户的业务逻辑程序代码 异步通知可能出现订单重复通知 需要做去重处理
                //获取回调信息
                BigDecimal total_amount = new BigDecimal(params.get("total_amount"));
                String flag = params.get("trade_status");
                if (!"TRADE_SUCCESS".equals(flag)){
                    return "success";
                }
                String passback_params = params.get("passback_params");
                ShopIngShangJiaForm shopIngShangJiaForm = JsonUtils.jsonToPojo(passback_params, ShopIngShangJiaForm.class);

                //充实Form
                shopIngShangJiaForm.setMoney(total_amount);
                userService.ShopIngShangJia(shopIngShangJiaForm);


                log.info("shopIng_shangJia_pay_url 验证成功succcess");
                return "success";
            } else {
                log.info("shopIng_shangJia_pay_url 验证失败");
                // TODO
                return "failure";
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return "failure";
        }
    }


    /**
     * 交易大厅 买家支付
     * @param request
     * @return
     */
    @RequestMapping(value = "/shop_Ing_Trading_url")
    @ResponseBody
    @PrintParam
    public String ShopIngTradingNotifyUrl(HttpServletRequest request) {
        try {
            Map<String, String> params = AliPayApi.toMap(request);
            // 获取支付宝POST过来反馈信息
            boolean verifyResult = rsaCertCheckV1(params);
            if (verifyResult) {
                // TODO 请在这里加上商户的业务逻辑程序代码 异步通知可能出现订单重复通知 需要做去重处理
                //获取回调信息
                BigDecimal total_amount = new BigDecimal(params.get("total_amount"));
                String flag = params.get("trade_status");
                if (!"TRADE_SUCCESS".equals(flag)){
                    return "success";
                }
                String passback_params = params.get("passback_params");
                ShopIngShangJiaForm shopIngShangJiaForm = JsonUtils.jsonToPojo(passback_params, ShopIngShangJiaForm.class);

                //充实Form
                shopIngShangJiaForm.setMoney(total_amount);
                //userService.ShopIngShangJia(shopIngShangJiaForm);
                shangjiaDealService.ShopIngShangJia(shopIngShangJiaForm);
                shangjiaDealService.shopPay(shopIngShangJiaForm);
                log.info("shopIng_shangJia_pay_url 验证成功succcess");
                return "success";
            } else {
                log.info("shopIng_shangJia_pay_url 验证失败");
                // TODO
                return "failure";
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return "failure";
        }
    }
    /**
     * 线下消费商户买卖
     *
     * @param request
     * @return
     */
    @RequestMapping(value = "/shop_offline_pay_url")
    @ResponseBody
    @PrintParam
    public String shopOfflinePayUrl(HttpServletRequest request) {
        try {

            Map<String, String> params = AliPayApi.toMap(request);
            // 获取支付宝POST过来反馈信息
            boolean verifyResult = rsaCertCheckV1(params);
            if (verifyResult) {
                // 获取用户 编号
                Object out_trade_no = redisCache.getCacheObject(params.get("out_trade_no"));
                log.info("out_trade_no:{}",out_trade_no);
                String flag = params.get("trade_status");
                if (!"TRADE_SUCCESS".equals(flag)){
                    return "success";
                }
                if (Objects.isNull(out_trade_no)){
                    out_trade_no = params.get("out_trade_no");
                    String jsonObj = params.get("passback_params");
                    JSONObject jsonObject = JSON.parseObject(jsonObj);
                    String userId = jsonObject.getString("userId");
                    log.info("shop_offline_pay_url 验证成功succcess,{}",params);

                    // 获取商户 编号
                    String shopId = jsonObject.getString("shopId");
                    // 获取支付金额
                    BigDecimal money = new BigDecimal(params.get("total_amount"));
                    if (money.compareTo(new BigDecimal(0))<=0){
                        return "success";
                    }
                    shopService.offlinePaySuccess(userId,shopId,money);
                }
                redisCache.setCacheObject(out_trade_no.toString(),out_trade_no);
                return "success";
            } else {
                log.info("shop_offline_pay_url 验证失败");

                return "success";
            }
        } catch (Exception e) {
            e.printStackTrace();
            return "success";
        }
    }

    /**
     * 统一验证信息
     */
    public boolean rsaCertCheckV1(Map<String, String> params)throws AlipayApiException{
        boolean verifyResult = AlipaySignature.rsaCertCheckV1(params, aliConfig.getAliPayCertPath(), "UTF-8", "RSA2");
        return verifyResult;
    }

}
